{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Python中类方法的第一个参数以self开始\n",
    "\n",
    "from collections import namedtuple\n",
    "from collections import OrderedDict\n",
    "from functools import reduce\n",
    "import tushare as ts\n",
    "import numpy as np\n",
    "\n",
    "class StockTradeDays(object):\n",
    "    def __init__(self, price_array, start_date, date_array=None):\n",
    "        #私有价格，日期，涨跌幅序列\n",
    "        self.__price_array = price_array\n",
    "        self.__date_array = self._init_days(start_date, date_array)\n",
    "        self.__change_array = self.__init_change()\n",
    "        #进行OrderedDict的组装\n",
    "        self.stock_dict = self._init_stock_dict()\n",
    "        \n",
    "    def __init_change(self):\n",
    "        '''\n",
    "        从Price_array生成change_array\n",
    "        :return:\n",
    "        '''\n",
    "        price_float_array = [float(price_str) for price_str in self.__price_array]\n",
    "        \n",
    "        #前后两日的收盘价格组合成序列\n",
    "        pp_array = [(price1,price2) for price1, price2 in zip(price_float_array[:-1],price_float_array[1:])]\n",
    "        change_array = list(map(lambda pp: reduce(lambda a,b: round((b-a)/a,3),pp),pp_array))\n",
    "        \n",
    "        change_array.insert(0,0)\n",
    "        return change_array\n",
    "    \n",
    "    def _init_days(self, start_date, date_array):\n",
    "        '''\n",
    "        protect方法\n",
    "        :param start_date：初始日期\n",
    "        :para date_array: 给定日期序列\n",
    "        :return:\n",
    "        '''\n",
    "        if date_array is None:\n",
    "            date_array = [str(start_date + ind) for ind, _ in enumerate(self.__price_array)]\n",
    "        else:\n",
    "            date_array = [str(date) for date in date_array]\n",
    "        return date_array\n",
    "    \n",
    "    def _init_stock_dict(self):\n",
    "        # '''\n",
    "        #使用namedtuple, OrderedDict将结果合并\n",
    "        #：return:\n",
    "        #'''\n",
    "        stock_namedtuple = namedtuple('stock',('date','price','change'))\n",
    "        stock_dict = OrderedDict((date, stock_namedtuple(date,price,change))\n",
    "                                 for date, price, change in zip(self.__date_array, self.__price_array,self.__change_array))\n",
    "        return stock_dict\n",
    "    \n",
    "    def filter_stock(self, want_up = True, want_calc_sum = False):\n",
    "        '''\n",
    "        筛选结果子集\n",
    "        :param want_up：True筛选上涨；False筛选下跌\n",
    "        :para want_calc_sum: 是否计算涨跌幅\n",
    "        :return:\n",
    "        '''\n",
    "        filter_func = (lambda day:day.change>0) if want_up else(lambda day: day.change<0 )\n",
    "        want_days = filter(filter_func, self.stock_dict.values())\n",
    "        if not want_calc_sum:\n",
    "            return want_days\n",
    "        change_sum = 0.0\n",
    "        for day in want_days:\n",
    "            change_sum +=day.change\n",
    "        return change_sum\n",
    "    \n",
    "    #其它的函数\n",
    "    def __str__(self):\n",
    "        return str(self.stock_dict)\n",
    "    __repr__ = __str__\n",
    "    \n",
    "    def __iter__(self):\n",
    "        for key in self.stock_dict:\n",
    "            yield self.stock_dict[key]\n",
    "            \n",
    "    def __getitem__(self, ind):\n",
    "        date_key = self.__date_array[ind]\n",
    "        return self.stock_dict[date_key]\n",
    "    \n",
    "    def __len__(self):\n",
    "        #print('i am here')\n",
    "        return len(self.stock_dict)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[stock(date='20170118', price=30.14, change=0), stock(date='20170119', price=29.56, change=-0.019), stock(date='20170120', price=26.36, change=-0.108), stock(date='20170121', price=32.56, change=0.235), stock(date='20170122', price=32.82, change=0.008)]\n",
      "trade_days对象长度为： 5\n",
      "stock(date='20170118', price=30.14, change=0)\n",
      "stock(date='20170119', price=29.56, change=-0.019)\n",
      "stock(date='20170120', price=26.36, change=-0.108)\n",
      "stock(date='20170121', price=32.56, change=0.235)\n",
      "stock(date='20170122', price=32.82, change=0.008)\n",
      "[stock(date='20170121', price=32.56, change=0.235), stock(date='20170122', price=32.82, change=0.008)]\n",
      "0.243\n",
      "[stock(date='20170119', price=29.56, change=-0.019), stock(date='20170120', price=26.36, change=-0.108)]\n",
      "-0.127\n"
     ]
    }
   ],
   "source": [
    "from collections import Iterable\n",
    "\n",
    "price_array = [30.14, 29.56, 26.36, 32.56, 32.82]\n",
    "date_base = 20170118\n",
    "\n",
    "trade_days =StockTradeDays(price_array, date_base)\n",
    "print(list(trade_days))\n",
    "print('trade_days对象长度为：',len(trade_days))\n",
    "\n",
    "if isinstance(trade_days, Iterable):\n",
    "    for day in trade_days:\n",
    "        print(day)\n",
    "        \n",
    "print(list(trade_days.filter_stock()))\n",
    "\n",
    "print(trade_days.filter_stock(True,True))\n",
    "\n",
    "print(list(trade_days.filter_stock(False)))\n",
    "\n",
    "print(trade_days.filter_stock(False,True))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tushare \n",
    "imp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "002241 的行情数据为:\n",
      "            date  open  close  high   low    volume    code\n",
      "141  2018-08-01  9.70   9.42  9.77  9.39  163617.0  002241\n",
      "142  2018-08-02  9.37   8.96  9.39  8.80  281673.0  002241\n",
      "143  2018-08-03  9.03   8.73  9.03  8.72  143977.0  002241\n",
      "144  2018-08-06  8.70   8.39  8.83  8.34  178779.0  002241\n",
      "145  2018-08-07  8.46   8.64  8.67  8.38  147798.0  002241\n",
      "146  2018-08-08  8.65   8.40  8.65  8.38  118325.0  002241\n",
      "147  2018-08-09  8.40   8.68  8.77  8.36  172437.0  002241\n",
      "148  2018-08-10  8.67   8.72  8.74  8.61  113611.0  002241\n",
      "149  2018-08-13  8.58   8.80  8.85  8.54  127820.0  002241\n",
      "150  2018-08-14  8.79   8.62  8.84  8.59  161701.0  002241\n",
      "151  2018-08-15  8.62   8.31  8.65  8.30  199160.0  002241\n",
      "152  2018-08-16  8.21   8.12  8.31  8.06  168213.0  002241\n",
      "['2018-08-01', '2018-08-02', '2018-08-03', '2018-08-06', '2018-08-07', '2018-08-08', '2018-08-09', '2018-08-10', '2018-08-13', '2018-08-14', '2018-08-15', '2018-08-16'] \n",
      " [9.42, 8.96, 8.73, 8.39, 8.64, 8.4, 8.68, 8.72, 8.8, 8.62, 8.31, 8.12]\n",
      "[stock(date='2018-08-07', price=8.64, change=0.03), stock(date='2018-08-09', price=8.68, change=0.033), stock(date='2018-08-10', price=8.72, change=0.005), stock(date='2018-08-13', price=8.8, change=0.009)]\n",
      "0.077\n",
      "[stock(date='2018-08-02', price=8.96, change=-0.049), stock(date='2018-08-03', price=8.73, change=-0.026), stock(date='2018-08-06', price=8.39, change=-0.039), stock(date='2018-08-08', price=8.4, change=-0.028), stock(date='2018-08-14', price=8.62, change=-0.02), stock(date='2018-08-15', price=8.31, change=-0.036), stock(date='2018-08-16', price=8.12, change=-0.023)]\n",
      "-0.22099999999999997\n"
     ]
    }
   ],
   "source": [
    "#print('当前Tushare版本为：',ts.__version__)\n",
    "#当前Tushare版本为： 1.2.12\n",
    "\n",
    "#获取股票历史行情数据\n",
    "stock_code = '002241'\n",
    "stock_array = ts.get_k_data(stock_code, start='2018-08-01')\n",
    "#print(stock_array.values)\n",
    "#print(stock_array.name)\n",
    "\n",
    "\n",
    "print(stock_code,'的行情数据为:\\n',stock_array)\n",
    "\n",
    "\n",
    "#date_array = [str(date) for date in date_array]\n",
    "\n",
    "date_list = [date for date in stock_array.date]\n",
    "\n",
    "price_array = [price for price in stock_array.close]\n",
    "\n",
    "print(date_list,'\\n',price_array)\n",
    "\n",
    "\n",
    "\n",
    "real_trade_days = StockTradeDays(price_array,20180801,date_list)\n",
    "print(list(real_trade_days.filter_stock()))\n",
    "\n",
    "print(real_trade_days.filter_stock(True,True))\n",
    "\n",
    "print(list(real_trade_days.filter_stock(False)))\n",
    "\n",
    "print(real_trade_days.filter_stock(False,True))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
